package common.util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import model.dap.dao.BusinessDAO;
import model.dap.dao.ConsumerDAO;
import model.dap.domain.Business;
import model.dap.domain.Consumer;
import model.dap.mapper.BusinessMapper;
import model.dap.mapper.ConsumerMapper;

import org.apache.log4j.Logger;

import com.opensymphony.xwork2.ActionSupport;

public class ValidateUtil extends ActionSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//public static final String REG_EMAIL = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$;";
	public static final String REG_EMAIL ="^[\\x01-\\x20\\x23-\\x26\\x28-\\x2B\\x2D-\\x39\\x3D\\x3F\\x41-\\x5A\\x5E-\\x7F]+@([-\\w]+\\.)+[-\\w]+$";
	private static final String NAME_STANDARD = "^[a-zA-Z0-9]{6,25}$";
	private static final String REG_DATE_FORMAT = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)";
	//private static final String REG_DATE_FORMAT = "^\\d{4}/\\d{2}/\\d{2}$";
	Consumer consumer = new Consumer();
	Business business = new Business();
	Logger log = Logger.getLogger(ValidateUtil.class);
	//======================================================================================================
	// ----------------------XU LY LOGIC, CHUA CAN LIEN KET DB
	/**
	 * VALIDATE LENGTH
	// BR.01.13 Password isn’t distinct uppercase and lowercase
	// BR.01.22 Email isn’t distinct uppercase and lowercase
	// BR.01.31 Address isn’t distinct uppercase and lowercase.
	// BR.01.09 Not modified Username.
	// BR.01.15 Account can be used by consumer to login (consumer needn't wait
	// to admin activate after register successfully)
	 * */
	//======================================================================================================
	// BR.01.11 Length of Password [6-50]
	public static boolean validateLengthOfPassword(String Password) {
		try {
			if (Password.trim().toLowerCase().length() >= 6
					&& Password.trim().toLowerCase().length() <= 50) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.25 Length of full name is from 6 to 50 characters.
	public static boolean validateLengthOfFullname(String Fullname) {
		try {
			if (Fullname.trim().toLowerCase().length() >= 6
					&& Fullname.trim().toLowerCase().length() <= 50) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.29 Length of address is from 10 to 100 characters.
	public static boolean validateLengthOfAddress(String Address) {
		try {
			if (Address.trim().toLowerCase().length() >= 10
					&& Address.toLowerCase().trim().length() <= 100) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.14 Password and Confirm Password is the same
	public static boolean validateConfirmPassword(String password,
			String confirmPassword) {
		try {
			if (password.trim().equalsIgnoreCase(confirmPassword.trim()) == true) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================
	
	/**
	 * VALIDATE NAME STANDARD
	// BR.01.04 Username (Business) just allow input [a-z] / [A-Z] / [0-9]
	//BR.01.48	Company name is only containt characters: a-z, A-Z, 0-9							
	//BR.01.49	Business domain is only containt characters: a-z, A-Z, 0-10							
	//BR.01.50	TaxID is only containt characters: a-z, A-Z, 0-11	
	 * */
	//======================================================================================================
							
	public static boolean validateNameStandard(String str) {
		try{
		   if(MiscUtils.regMatch(NAME_STANDARD, str)==true)
	            return true;
		}
		catch (Exception e) {
			return false;
		}
		return false;
		
	}
	// ======================================================================================================================

	// BR.01.35 Birthday must format DD/MM/YYYY.
	/**
     * Check the date format as dd/MM/yyyy
     * @param dateFormatString
     * @return
     */
	
	  public static boolean validateDateFormat(String dateFormatString)
	    {
	    	// First check for the pattern
	        if(!MiscUtils.regMatch(REG_DATE_FORMAT, dateFormatString))
	            return false;

	        // Parse the date parts to integers
	        String[] parts = dateFormatString.split("/");
	        int day = Integer.parseInt(parts[0], 10);
	        int month = Integer.parseInt(parts[1], 10);
	        int year = Integer.parseInt(parts[2], 10);

	        // Check the ranges of month and year
	        if(year < 1000 || year > 3000 || month == 0 || month > 12)
	            return false;

	        int[] monthLength = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

	        // Adjust for leap years
	        if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
	            monthLength[1] = 29;

	        // Check the range of the day
	        return (day > 0 && day <= monthLength[month - 1]);
	    }
	
	
	

	// ======================================================================================================================

	// BR.01.19 Email must follow standard AccountName@DomainName (AccountName
	// can be different with Consumer ID)
	public static boolean validateEmailStandard(String email) {
		if (validateEmptyString(email) == false)
		{
			return MiscUtils.regMatch(REG_EMAIL,email);
    	}
    	return false;
	}
	//======================================================================================================
	/** VALIDATE EMPTY
	// BR.01.30 Address isn't empty.
	// BR.01.32 District isn't empty.
	// BR.01.33 City isn't empty.
	// BR.01.34 Phone number isn't empty.
	// BR.01.36 Company name isn't empty.
	// BR.01.38 Tax ID isn't empty.
	// BR.01.40 Business domain isn't empty.
	 */
	//======================================================================================================

	public static boolean validateEmptyString(String str) {
		try {
			if (str.trim() == null || str.trim().toString().equals("")) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.37 Length of company name isn't from 6 to 200 characters.
	public static boolean validateLengthOfCompanyName(String companyname) {
		try {
			if (companyname.trim().length() >= 6
					&& companyname.trim().length() <= 200) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.39 Length of tax ID is from 6 to 50 characters.
	public static boolean validateLengthOfTaxID(String taxid) {
		try {
			if (taxid.trim().length() >= 6 && taxid.trim().length() <= 15) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.41 Length of business domain is from 6 to 50 characters.
	public static boolean validateLengthOfBusinessDomain(String businessDomain) {
		try {
			if (businessDomain.trim().length() >= 6
					&& businessDomain.trim().length() <= 50) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// UserID is only 6-25 characters
	public static boolean validateLengthOfUserID(String userID) {
		try {
			if (userID.trim().length() >= 6 && userID.trim().length() <= 25) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	public static boolean validateLengthOfPhoneNumber(String phoneNumber) {
		try {
			if (phoneNumber.trim().length() >= 10
					&& phoneNumber.trim().length() <= 20) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// MD5 Encryption
	private static String convertedToHex(byte[] data) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < data.length; i++) {
			int halfOfByte = (data[i] >>> 4) & 0x0F;
			int twoHalfBytes = 0;
			do {
				if ((0 <= halfOfByte) && (halfOfByte <= 9)) {
					buf.append((char) ('0' + halfOfByte));
				}

				else {
					buf.append((char) ('a' + (halfOfByte - 10)));
				}

				halfOfByte = data[i] & 0x0F;

			} while (twoHalfBytes++ < 1);
		}
		return buf.toString();
	}

	public static String MD5Encryption(String text)
			throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest md;
		md = MessageDigest.getInstance("MD5");
		byte[] md5 = new byte[64];
		md.update(text.getBytes("iso-8859-1"), 0, text.length());
		md5 = md.digest();
		return convertedToHex(md5);
	}
	//======================================================================================================

	// -----------------------XU LU LOGIC, CAN LIEN KET DB
	// BR.01.03 Consumer account must be active.
	// Xem xet xem consumer do da active hay chua
	public static boolean validateActiveConsumer(String userID) {
		try {
			ConsumerMapper consumerMapper = new ConsumerDAO();
			Consumer consumerDB = consumerMapper.validateActiveConsumer(userID.trim());
			if (consumerDB.getUserStatus().equalsIgnoreCase("Active") == true) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.05 Username (Business) is only and isn't duplicate in system
	public static boolean validateBusinessExist(String userID) {
		try {
			BusinessMapper businessMapper = new BusinessDAO();
			Business businessDB = businessMapper.validateBusinessExist(userID);
			if (businessDB == null) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.08 Username is only and exist in system if consumer wants retrieve
	// password.
	public static boolean validateConsumerExist(String userID) {
		try {
			ConsumerMapper consumerMapper = new ConsumerDAO();
			Consumer consumerDB = consumerMapper.validateConsumerExist(userID);
			if (consumerDB == null) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.16 Consumer login wrong 5 times in 30 minutes present CAPTCHA code.
	//======================================================================================================

	// BR.01.18 Business account doesn't login into system.
	public static boolean validateConsumerOrNot(String userID) {
		try {
			ConsumerMapper consumerMapper = new ConsumerDAO();
			Consumer consumerDB = consumerMapper.validateConsumerOrNot(userID);
			if (consumerDB.getUserTypeID() != 4) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	// BR.01.21 Email is only and isn't duplicate in system.
	public static boolean validateBusinessEmailExist(String email) {
		try {
			BusinessMapper businessMapper = new BusinessDAO();
			Business businessDB = businessMapper.validateBusinessEmailExist(email.trim());
			if (businessDB == null) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}

	//======================================================================================================
	// BR.01.17 One account just login at the same on the place (one browser,
	// laptop)
	public static boolean validateConsumerLogedin(String userID) {
		try {
			ConsumerMapper consumerMapper = new ConsumerDAO();
			Consumer consumerDB = consumerMapper.validateConsumerStatus(userID.trim());
			if (consumerDB.getUserStatus().equalsIgnoreCase("Logged in") == true) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	public static boolean validateConsumerEmailExist(String email) {
		try {
			ConsumerMapper consumerMapper = new ConsumerDAO();
			Consumer consumerDB = consumerMapper
					.validateConsumerEmailExist(email.trim());
			if (consumerDB == null) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	//======================================================================================================

	public static boolean validateOldPassword (Consumer mastuser ){
		try {
			ConsumerMapper consumerMapper = new ConsumerDAO();
			Consumer consumerDB = consumerMapper.validateOldPassword(mastuser);
			if (consumerDB != null) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	public static boolean validateEmptyQuanity(int num) {
		try {
			if (String.valueOf(num).equals("") || String.valueOf(num).equals(null) ||  num==0) {
				return true;
			}
		} catch (Exception e) {
			return false;
		}
		return false;
	}
	
	// validate temporary password
		public static boolean validateTemporaryPassword(String temporaryPassword)
		{
			try {
				ConsumerMapper consumerMapper = new ConsumerDAO();
				Consumer consumer = consumerMapper.validateTemporaryPassword(temporaryPassword);
				if(consumer != null)
					return true;
			} catch (Exception e) {
				// TODO: handle exception
				return false;
			}
			return true;
		}
		// validate email matching userID
				public static boolean validateEmailMatchUserID(Consumer user)
				{
					try {
						ConsumerMapper consumerMapper = new ConsumerDAO();
						Consumer consumer = consumerMapper.validateEmailMatchUserID(user);
						if(consumer != null)
							return true;
					} catch (Exception e) {
						// TODO: handle exception
						return false;
					}
					return false;
				}
}
